<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <!-- 侦听器：用来监听数据的改变 -->
      <!-- 并且侦听器可以支持异步操作 -->
      <h2>侦听器</h2>
      <p>name: {{ name }}</p>
      <p>count: {{ count }}</p>
      <button @click="count++">count++</button>

      <hr>

      <p class="box">obj: {{ obj }}</p>
      <button @click="obj.age++">change obj</button>

      <hr>

      <p>num: {{ num }}</p>
      <button @click="num++">num++</button>
      <br>
      <button @click="start">开启监听</button>
      <button @click="stop">停止监听</button>
    </div>

    <script src="./lib/vue3.js"></script>
    <script>
      const { createApp } = Vue;

      let unwatch;

      createApp({
        data() {
          return {
            name: 'document',
            count: 1,
            obj: {
              name: "xiaohua",
              age: 18
            },
            num: 1
          }
        },
        methods: {
          start() {
            // this.$watch表示开启watch监听
            unwatch = this.$watch("num", (val, oldVal) => {
              console.log(`num的值从${oldVal}变成了${val}`);
            })
          },
          stop() {
            // unwatch?.();
            unwatch && unwatch();
            // const name = localStorage.getItem("name") || "admin"
          }
        },
        watch: {
          // watch函数可以接受两个参数，分别是改变后的值和改变前的值
          count(val, oldVal) {
            setTimeout(() => {
              console.log("count改变了", val, oldVal);
            }, 1000)
          },
          // 只能监听对象下面的某一个属性的变化
          // "obj.age"() {
          //   console.log("obj改变了");
          // },
          obj: {
            handler(val, oldVal) {
              console.log("obj改变了", val, oldVal);
              console.log(document.querySelector(".box")?.innerHTML);
            },
            deep: true, // 深度监听(可以监听复杂数据类型的值的改变了)
            immediate: true, // 强制立即执行回调(进入页面的时候先做一次)
            // 默认情况下监听的回调会在页面重新渲染之前调用
            // 当加上flush: 'post'，监听的回调会在页面重新渲染之后调用
            flush: 'post'
          }
        }
      }).mount("#app");
    </script>
  </body>
</html>
